package ServerSide;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.StringTokenizer;

import Handlers.ServerHandler;


/**
 * @author Avishai Kopeliansky 
 * @ID 066717752
 * @author David Shimshon
 * @ID 038185617
 */
public class ClientSock extends Thread{
	private BufferedReader in;
	private PrintWriter out;
	private Socket sock;
	private boolean flag = true;
	private static int ID = 0;
	private String name;
	private ClientHandling ch;

	/**
	 * Constructor 
	 * @param sock Connection Socket
	 * @param ch	Client Handler
	 */
	public ClientSock(Socket sock, ClientHandling ch)
	{
		ID++;
		this.sock = sock;
		this.ch = ch;
		try {
			this.in = new BufferedReader(new InputStreamReader(this.sock.getInputStream()));
			this.out = new PrintWriter(this.sock.getOutputStream(),true);
		}
		catch (UnknownHostException e) {
			e.printStackTrace();

		} 
		catch (IOException e) {
			e.printStackTrace();

		}
	}

	/**
	 * Get the user name
	 * @return name - user name
	 */
	public String getNames(){
		return this.name;
	}

	/**
	 * @return ID - connection ID
	 */
	@SuppressWarnings("static-access")
	public int getID(){
		return this.ID;
	}

	public void run() {
		String input = "";
		ServerHandler sh = new ServerHandler(this.ch,this,out);
		try {
			while(this.flag){
				input = this.in.readLine();				
				StringTokenizer st = new StringTokenizer(input, "<>");				
				if(st.hasMoreTokens()){
					String s =st.nextToken();
					//connection request
					if(!s.equalsIgnoreCase("auth")){
						if(st.hasMoreTokens()){
							String t= "<";
							while(st.hasMoreTokens()){
								t+=st.nextToken();
								t+=">";
							}
							sh.sorter(s, t, out, null);
						}
						else
							sh.sorter(s,s,out,null);
					}
					else
					{
						this.name = st.nextToken();
						if(ch.hasName(name)){
							this.name = nameInc(name);
							this.out.println("<smsg><Newnick:"+this.name+">");

						}

						ch.permAdd(this);
						ch.removeTemp(this.getID());
						this.out.println("<connected>");
						this.out.println("<UserList><" + this.ch.clientList());

					}
				}
			}
			this.out.println("<UserList><" + this.ch.clientList());
			this.sock.close();
			try{
				Thread.sleep(100l);
			}
			catch(Exception e){};
			this.ch.removeMe(this.getNames());

			System.out.println(name+"closed");
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	/**
	 * Dispatch  Broadcast Message
	 * @param msg The Message
	 */
	public void sendMsg(String msg){

		this.out.println("<umsg><"+msg+">");
	}

	private String nameInc(String name)
	{
		String t = name;
		int i = 1;
		while(true){

			if(!this.ch.hasName(t+i)){
				t= t+i;
				break;
			}
			else
				i++;

		}
		return t;
	}
	/**
	 * Dispatch System Message
	 * @param msg The Message
	 */
	public void sendSMsg(String msg){
		this.out.println(msg);
	}
	/**
	 * Close the loop of this socket
	 */
	public void shutDown() {
		this.flag = false;

	}


	/**
	 * Dispatch Personal Message
	 * @param msg The Message
	 */
	public void sendPMsg(String msg) {
		this.out.println("<msg><"+"PM:"+msg+">");

	}

}





